package cz.muni.fi.hauntedhousesclient;

import com.fasterxml.jackson.databind.JsonNode;
import cz.muni.fi.hauntedhouses.to.GhostTO;
import cz.muni.fi.hauntedhouses.type.Cas;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.sourceforge.stripes.action.*;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

/**
 *
 * @author Jan Volmut
 */
@UrlBinding("/ghosts/{$event}/{ghost.id}")
public class GhostActionBean implements ActionBean {

    static final String STROJ = "localhost";
    static final int PORT = 8080;
    static final String WEBAPP = "pa165";
    static final String URL = "http://" + STROJ + ":" + PORT + "/" + WEBAPP + "/rest/";
    private ActionBeanContext context;
    private float Cas;

    @Override
    public void setContext(ActionBeanContext context) {
        this.context = context;
    }

    @Override
    public ActionBeanContext getContext() {
        return context;
    }

    @DefaultHandler
    public Resolution all() {
        return new ForwardResolution("/showGhosts.jsp");

    }

    public List<GhostTO> getGhosts() {
        List<GhostTO> list = new ArrayList<GhostTO>();
        RestClient client = authenticate();

        String apiurl=client.apiUrl("ghosts");
        System.err.println("apiurl:"+apiurl);
        
        System.err.println("json call:"+client.template().getForObject(apiurl, String.class).toString());
        JsonNode jsonNode = client.template().getForObject(URL+"ghosts",
                JsonNode.class);
        
        if (jsonNode != null) {
            List<JsonNode> nodes = jsonNode.findValues("ghostTO");
            JsonNode innerNode = nodes.get(0);
            if (!innerNode.isArray()) {
                GhostTO ghost = new GhostTO();
                if (innerNode.get("id") != null) {
                    ghost.setId(innerNode.get("id").asLong());
                }
                if (innerNode.get("name") != null) {
                    ghost.setName(innerNode.get("name").asText());
                }
                if (innerNode.get("description") != null) {
                    ghost.setDescription(innerNode.get("description").asText());
                }
                if (innerNode.get("power") != null) {
                    ghost.setPower(innerNode.get("power").asLong());
                }
                if (innerNode.get("hauntingFrom") != null) {
                    String time = innerNode.get("hauntingFrom").asText();
                    Cas cas = new Cas(time.substring(time.indexOf('T') + 1, time.indexOf('+')));
                    ghost.setHauntingFrom(cas);
                }
                if (innerNode.get("hauntingTo") != null) {
                    String time = innerNode.get("hauntingTo").asText();
                    Cas cas = new Cas(time.substring(time.indexOf('T') + 1, time.indexOf('+')));
                    ghost.setHauntingTo(cas);
                }
                list.add(ghost);
            } else {
                Iterator<JsonNode> iter = innerNode.elements();
                while (iter.hasNext()) {
                    JsonNode node = iter.next();
                    GhostTO g = new GhostTO();
                    if (node.get("id") != null) {
                        g.setId(node.get("id").asLong());
                    }
                    if (node.get("name") != null) {
                        g.setName(node.get("name").asText());
                    }
                    if (node.get("description") != null) {
                        g.setDescription(node.get("description").asText());
                    }
                    if (node.get("power") != null) {
                        g.setPower(node.get("power").asLong());
                    }
                    if (node.get("hauntingFrom") != null) {
                        String time = node.get("hauntingFrom").asText();
                        Cas cas = new Cas(time.substring(time.indexOf('T') + 1, time.indexOf('+')));
                        g.setHauntingFrom(cas);
                    }
                    if (node.get("hauntingTo") != null) {
                        String time = node.get("hauntingTo").asText();
                        Cas cas = new Cas(time.substring(time.indexOf('T') + 1, time.indexOf('+')));
                        g.setHauntingTo(cas);
                    }
                    list.add(g);
                }
            }

        }
        return list;
    }
    @ValidateNestedProperties(value = {
        @Validate(on = {"add", "save"}, field = "name", required = true),
        @Validate(on = {"add", "save"}, field = "power", required = true, minvalue = 0, maxvalue = 100),
        @Validate(on = {"add", "save"}, field = "hauntingFrom", mask = "^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"),
        @Validate(on = {"add", "save"}, field = "hauntingTo", mask = "^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$")
    })
    private GhostTO ghost;

    public GhostTO getGhost() {
        return ghost;
    }

    public void setGhost(GhostTO ghost) {
        this.ghost = ghost;
    }

    public Resolution add() {
        RestClient client = authenticate();
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<String> entity = new HttpEntity<String>(headers);
        if (ghost.getDescription() == null) {
            client.template().put(URL + "ghosts?name=" + ghost.getName() + "&power=" + ghost.getPower() + "&hauntingFrom=" + ghost.getHauntingFrom() + "&hauntingTo=" + ghost.getHauntingTo(), entity);
        } else {
            client.template().put(URL + "ghosts?name=" + ghost.getName() + "&power=" + ghost.getPower() + "&hauntingFrom=" + ghost.getHauntingFrom() + "&hauntingTo=" + ghost.getHauntingTo() + "&description=" + ghost.getDescription(), entity);
        }
        return new RedirectResolution(this.getClass(), "all");
    }

    public Resolution delete() {
        RestClient client = authenticate();
        client.template().delete(URL + "ghosts/" + ghost.getId());
        return new RedirectResolution(this.getClass(), "all");
    }

    @Before(stages = LifecycleStage.BindingAndValidation, on = {"edit", "save"})
    public void loadGhostFromDatabase() {
        String ids = context.getRequest().getParameter("ghost.id");
        if (ids != null) {

            String url = URL + "ghosts/" + Long.parseLong(ids);

            RestClient client = authenticate();

            JsonNode jsonNode = client.template().getForObject(url, JsonNode.class);
            GhostTO g = new GhostTO();
            System.out.println(jsonNode.toString());
            if (jsonNode != null) {
                if (jsonNode.get("id") != null) {
                    g.setId(jsonNode.get("id").asLong());
                }
                if (jsonNode.get("name") != null) {
                    g.setName(jsonNode.get("name").asText());
                }
                if (jsonNode.get("description") != null) {
                    g.setDescription(jsonNode.get("description").asText());
                }
                if (jsonNode.get("power") != null) {
                    g.setPower(jsonNode.get("power").asLong());
                }
                if (jsonNode.get("hauntingFrom") != null) {
                    String time = jsonNode.get("hauntingFrom").asText();
                    Cas cas = new Cas(time.substring(time.indexOf('T') + 1, time.indexOf('+')));
                    g.setHauntingFrom(cas);
                }
                if (jsonNode.get("hauntingTo") != null) {
                    String time = jsonNode.get("hauntingTo").asText();
                    Cas cas = new Cas(time.substring(time.indexOf('T') + 1, time.indexOf('+')));
                    g.setHauntingTo(cas);
                }

            }
            ghost = g;
        }
    }

    public Resolution edit() {
        return new ForwardResolution("/editGhost.jsp");
    }

    public Resolution save() {
        RestClient client=authenticate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<String> entity = new HttpEntity<String>(headers);
        if (ghost.getDescription() == null) {
            client.template().postForLocation(URL + "ghosts/" + ghost.getId() + "?name=" + ghost.getName() + "&power=" + ghost.getPower() + "&hauntingFrom=" + ghost.getHauntingFrom() + "&hauntingTo=" + ghost.getHauntingTo(), entity);
        } else {
            client.template().postForLocation(URL + "ghosts/" + ghost.getId() + "?name=" + ghost.getName() + "&power=" + ghost.getPower() + "&hauntingFrom=" + ghost.getHauntingFrom() + "&hauntingTo=" + ghost.getHauntingTo() + "&description=" + ghost.getDescription(), entity);
        }
        return new RedirectResolution(this.getClass(), "all");
    }

    public Resolution cancel() {
        return new RedirectResolution(this.getClass(), "all");
    }

    public RestClient authenticate() {
        RestClient client = new RestClient();
        
        client.setApplicationPath(WEBAPP);
        String url1 = client.login("rest", "rest");
        
        return client;
    }
}